package Map;

import java.io.InputStream;
import java.util.*;

/**
 * @Grup:Map
 * @Auther:cola
 * @Data:2021/3/28-2021-03-14:11
 * @version:1.0 Map接口:
 * 1.键值对存储一组对象
 * 2.Key不能重复(唯一),value可以重复
 * 3.具体的实现类:HashMap TreeMap Hashtable LinkedHashMap
 * 4.HashMap与Hashtable的区别
 * <p>
 * 5.如何选择使用那个?
 * 6.数据结构:数组,链表,二叉树(红黑树),哈希表(数组+链表),栈,队列
 */
public class MapDemo {
    /*
     * 基于二叉树的红黑树实现
     * */
    private static void treeMap() {
        Map<String, String> tree = new TreeMap<>();
        tree.put("one", "lily");
        tree.put("two", "Tom");
        tree.put("three", "Ben");
        tree.forEach((key, value) -> System.out.println(key + "->" + value));


    }

    /*
     * LinkedHashMap是HashMap的子类,由于HashMap不能保证恒久不变,此类使用一个双重链表来维护
     * 元素添加的顺序.
     * */
    private static void linkedHashMap() {
        Map<String, String> table = new LinkedHashMap<>();
        table.put("one", "lily");
        table.put("two", "Tom");
        table.put("three", "Ben");
        table.forEach((key, value) -> System.out.println(key + "->" + value));
    }

    /*
     * JDk1.0开始
     * 基于哈希表实现(数组+链表)
     * 默认数组大小为11,加载因子为0.75
     * 扩充方式:原数组大小<<1(*2)+1
     * 线程安全的,在多线程访问时
     * */
    private static void hashTable() {
        Map<String, String> table = new Hashtable<>();
        table.put("one", "lily");
        table.put("two", "Tom");
        table.put("three", "Ben");
        table.forEach((key, value) -> System.out.println(key + "->" + value));
    }

    /*
     * hashMap的实现原理
     * 1.基于哈希表(数组+链表+二叉树(红黑树))1.8
     * 2.默认加载因子为0.75,默认数组大小为16
     * 3.把对象存储到哈希表中,
     * 把对象存储到哈希表中,如何存储?
     * 把key对象通过hash()方法计算hash值,然后用这个hash值对数组长度取余数(默认16),来决定该key对象在数组中
     * 存储的位置,但这个位置有多个对象时,以链表结构存储mjdk1.8后,当链表长度大于8时,链表将转化为红黑树结构存储.
     * 这样的目的,是为了取值更快,存储的数据量越大,性能表现越明显
     *
     * 4.扩充原理:当数组的容量超过75%,那么表示数组需要扩充,如何扩充?
     * 扩充的算法是:当前容量<<1(相当于是乘于2),扩大1倍.扩充次数过多,会影响性能,每次扩充表示哈希表重新散列(重新计算每个对象的存储位置)
     * 我们在开发过程中尽量要减少扩充次数带来的性能问题.
     * 5.线程不安全的,适合在单线程中使用
     * */
    private static void hashMap() {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "tom");
        map.put(2, "jack");
        map.put(3, "啊大福大");
        System.out.println("size=" + map.size());
        //从map中取值
        System.out.println(map.get(1));//通过key取value

        //map的遍历
        //1.遍历键and值
        Set<Map.Entry<Integer, String>> entrieset = map.entrySet();
        for (Map.Entry e : entrieset) {
            System.out.println(e.getKey() + "->" + e.getValue());
        }

        //2.遍历键
        Set<Integer> keys = map.keySet();
        for (Integer i : keys) {
            String value = map.get(i);
            System.out.println(i + "->" + value);
        }
        //3.遍历值
        Collection<String> values = map.values();
        for (String value : values) {
            System.out.println(value);
        }

        //4 foreach
        map.forEach((key, value) -> System.out.println(key + "--->" + value));

        System.out.println(map.containsKey(7));
    }

    public static void main(String[] args) {
        //hashMap();
        //hashTable();
        treeMap();
    }
}
